package com.sbp.message.api.entity;

import com.dap.dao.BasePo;
import com.sbp.message.api.common.OperatePropertiesUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.util.Date;

public class Message extends BasePo {
    private static final Logger logger = LoggerFactory.getLogger(Message.class);
    private static String localMessageSource;
    static {
        Throwable error = null;

        if (StringUtils.isEmpty(localMessageSource)) {
            try {
                URL url = Message.class.getClassLoader().getResource("");
                localMessageSource = OperatePropertiesUtils.readValue(url.getPath() + "/config/bootstrap.properties", "app.name");
            } catch (Throwable throwable) {
                error = throwable;
            }
        }

        if (StringUtils.isEmpty(localMessageSource)) {
            try {
                URL url = Message.class.getClassLoader().getResource("");
                localMessageSource = OperatePropertiesUtils.readValue(url.getPath() + "/config/gateway.properties", "app.name");
            } catch (Throwable throwable) {
                error = throwable;
            }
        }

        if (StringUtils.isEmpty(localMessageSource)) {
            logger.warn("cannot read app.name form config file", error);
        }
    }

    public String id;
    public String destination;
    public String source;//队列对应源系统标识
    public String content;//内容
    public String groupName;//通知组名
    public int retry = 0;//重试次数
    public int messageType = MessageType.MESSAGE_QUEUE.getValue();
    public int status = MessageStatus.MessageStatus_unconfirmed.getValue();
    public int isPersistence = 1;// 0:透传非持久化; 1:持久化
    public int acknowledges = 0;//当前成功确认数量
    public int businessFailed = 0;  //只能人工处理的业务异常的数量
    public String acknowledgesDescribe;//确认者信息组成
    public int consumers = 0;//该条消息的消费者数量，适应于一对多的订阅
    public String consumersDescribe;//消费者信息描述
    public String unexpectedConsumersDescribe; //意外消费的消费者名称
    public Date createTime;
    public Date updateTime;
    public String traceId = MDC.get(com.dap.commons.Constants.TRACE_ID);
    public String errorMessage;
    public byte[] errorLog;//错误日志


    public Message() {
        if (null == source) source = localMessageSource;

        Date date = new Date();
        if (null == createTime) createTime = date;
        if (null == updateTime) updateTime = date;
    }

    public Message(String destination, String content) {
        Message(destination, content, destination, this.retry, MessageType.MESSAGE_QUEUE.getValue());
    }

    public void Message(String destination, String content, String groupName, int retry, int messageType) {
        if (null == source) source = localMessageSource;

        Date date = new Date();
        if (null == createTime) createTime = date;
        if (null == updateTime) updateTime = date;

        this.destination = destination;
        this.content = content;
        this.groupName = groupName;
        this.retry = retry;
        this.messageType = messageType;
    }

    public Message(String destination, String content, String groupName, int retry, int messageType, Date createTime, Date updateTime) {
        if (null == source) source = localMessageSource;

        this.createTime = createTime;
        this.updateTime = updateTime;

        this.destination = destination;
        this.content = content;
        this.groupName = groupName;
        this.retry = retry;
        this.messageType = messageType;
    }

    public static Message generateTopicMessage(String destinationSuffix, String content) {
        Message message = new Message();

        message.content = content;
        message.retry = 0;
        message.messageType = MessageType.MESSAGE_TOPIC.getValue();

        message.setTopicMessageDestinationAndGroupNameBySuffix(destinationSuffix);
        return message;
    }


    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getDestination() {
        return destination;
    }
    public void setDestination(String destination) {
        this.destination = destination;
    }
    public String getSource() {
        return source;
    }
    public void setSource(String source) {
        this.source = source;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getGroupName() {
        return groupName;
    }
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }
    public int getRetry() {
        return retry;
    }
    public void setRetry(int retry) {
        this.retry = retry;
    }
    public int getMessageType() {
        return messageType;
    }
    public void setMessageType(int messageType) {
        this.messageType = messageType;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public int getIsPersistence() {
        return isPersistence;
    }
    public void setIsPersistence(int isPersistence) {
        this.isPersistence = isPersistence;
    }
    public int getAcknowledges() {
        return acknowledges;
    }
    public void setAcknowledges(int acknowledges) {
        this.acknowledges = acknowledges;
    }
    public int getBusinessFailed() {
        return businessFailed;
    }
    public void setBusinessFailed(int businessFailed) {
        this.businessFailed = businessFailed;
    }
    public String getAcknowledgesDescribe() {
        return acknowledgesDescribe;
    }
    public void setAcknowledgesDescribe(String acknowledgesDescribe) {
        this.acknowledgesDescribe = acknowledgesDescribe;
    }
    public int getConsumers() {
        return consumers;
    }
    public void setConsumers(int consumers) {
        this.consumers = consumers;
    }
    public String getConsumersDescribe() {
        return consumersDescribe;
    }
    public void setConsumersDescribe(String consumersDescribe) {
        this.consumersDescribe = consumersDescribe;
    }
    public String getUnexpectedConsumersDescribe() {
        return unexpectedConsumersDescribe;
    }
    public void setUnexpectedConsumersDescribe(String unexpectedConsumersDescribe) {
        this.unexpectedConsumersDescribe = unexpectedConsumersDescribe;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getUpdateTime() {
        return updateTime;
    }
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
    public String getTraceId() {
        return traceId;
    }
    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }
    public String getErrorMessage() {
        return errorMessage;
    }
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
    public byte[] getErrorLog() {
        return errorLog;
    }
    public void setErrorLog(byte[] errorLog) {
        this.errorLog = errorLog;
    }


    @Override
    public String toString() {
        return "Message [id=" + id + ", destination=" + destination + ", source="
                + source + ", content=" + content + ", groupName=" + groupName + ", retry="
                + retry + ", messageType=" + messageType + ", status=" + status + ", createTime="
                + createTime + ", updateTime=" + updateTime + "]";
    }

    @Override
    public int hashCode() {
        return toString().hashCode();
    }


    /**
     * 只需要传入topic消息组名的后缀即可设置
     * 如一个一对多的topic消息, 需要将 destination 和 groupName 都设置为 VirtualTopic.xxx
     * 只需要 执行 setTopicMessageDestinationAndGroupNameBySuffix("xxx")
     * **/
    public void setTopicMessageDestinationAndGroupNameBySuffix(String suffix) {
        String topicDestination = "VirtualTopic." + suffix;
        this.destination = topicDestination;
        this.groupName = topicDestination;
    }
}
